/*
 * WeightHistoryComponent.java
 *
 * Created on 10 de Julho de 2011, 12:29
 */

package intopo.demonstrator.partnerclassification.gui;

import intopo.demonstrator.partnerclassification.State;
import intopo.demonstrator.partnerclassification.Parameters;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;

import util.math.Rational;
import util.gui.Plot2D;

import java.awt.*;
import java.beans.*;
import java.io.Serializable;

/**
 * A component that displays the history of the state of the partner classification model.
 *
 * @author pedro
 */
abstract public class AbstractStateHistoryComponent
	extends Plot2D
	implements Serializable
{
//	/**
//	 * State history that contains the information shown by this component.
//	 */
//	final protected java.util.Vector<State> history;
//	protected Parameters parameters;
//	/**
//	 * Dimension of the area where the history can be painted.
//	 */
//	final protected Dimension canvas;
//	/**
//	 * Position of the upper left anchor of the area where history can be painted.
//	 */
//	final protected Point canvasAnchor;
	private PropertyChangeSupport propertySupport;
	/**
	 * Font used to draw labels in the component.
	 */
	static final protected Font labelFont = new Font ("Times", Font.PLAIN, 10);

	public AbstractStateHistoryComponent ()
	{
		propertySupport = new PropertyChangeSupport (this);
//		canvas = new Dimension ();
//		canvasAnchor = new Point ();
		setXLabel ("time");
		adjustXRange ();
		setMinimumSize (new Dimension (200, 200));
		setPreferredSize (new Dimension (300, 300));
		setMaximumSize (new Dimension (1000, 1000));
		this.addComponentListener (new Listener ());
	}
	/**
	 * Sets the parameters of the partner classification model. This resets the information shown in this component.
	 */
	public void parametersChanged ()
	{
		adjustXRange ();
		repaint ();
	}
	/**
	 * Adds a new state to the history. Causes this component to be repainted.
	 */
	final public void newTransition ()
	{
		adjustXRange ();
		this.repaint ();
	}
	
	final public void addPropertyChangeListener (PropertyChangeListener listener)
	{
		propertySupport.addPropertyChangeListener (listener);
	}
	
	final public void removePropertyChangeListener (PropertyChangeListener listener)
	{
		propertySupport.removePropertyChangeListener (listener);
	}

	@Override
	final public void paint (Graphics g)
	{
		super.paint (g);
		paintHistory (g);
	}
	abstract protected void paintHistory (Graphics g);
	/**
	 * Adjusts the x range in order to show the last states in the history.
	 */
	final protected void adjustXRange ()
	{
		int space = (getWidth () - margin.left - margin.right + 1) / 2;
		if (space > Model.history.size ()) {
			setXRange (0, space);
			setXTics (0, 20, space);
		}
		else {
			setXRange (Model.history.size () - space, Model.history.size ());
			setXTics (Model.history.size () - space, 20, Model.history.size ());
		}
	}
//	final public void paintComponent (Graphics g)
//	{
//		int height = getHeight ();
//		g.setColor (Color.white);
//		g.fillRect (0, 0, getWidth (), height);
//		if (history != null && parameters != null) {
//			this.canvas.width = getWidth ();
//			this.canvas.height = getHeight ();
//			this.canvasAnchor.x = 0;
//			this.canvasAnchor.y = 0;
//			paintHistory (g);
//		}
//	}
//	/**
//	 * Paints the axis with the given label in the horizontal axis. Adjusts the canvas area.
//	 */
//	protected void paintAxis (Graphics g, String horizontalLabel)
//	{
//		int bottomMargin;
//		FontMetrics fm;
//		fm = g.getFontMetrics (labelFont);
//		g.setFont (labelFont);
//		g.setColor (Color.BLACK);
//		bottomMargin = fm.getHeight ();
//		g.drawString (horizontalLabel,
//			this.getWidth () - fm.stringWidth (horizontalLabel) - 10,
//			this.getHeight () - bottomMargin + fm.getAscent ());
//		drawArrow (g, 10, getHeight () - bottomMargin, getWidth () - 1, getHeight () - bottomMargin);
////		g.drawLine (
////			0, getHeight () - bottomMargin,
////			getWidth () - 1, getHeight () - bottomMargin);
////		g.drawLine (
////			getWidth () - 1, getHeight () - bottomMargin,
////			getWidth () - 6, getHeight () - bottomMargin - 5);
////		g.drawLine (
////			getWidth () - 1, getHeight () - bottomMargin,
////			getWidth () - 6, getHeight () - bottomMargin + 5);
//		canvas.height -= bottomMargin;
////		drawArrow (g, 10, getHeight () - bottomMargin, 10, 10);
////		Graphics2D g2d = (Graphics2D) g;
////		g2d.translate (50, 100);
////		for (int i = 0; i < 8; i++) {
////			g2d.rotate (-Math.PI / 4);
////			g2d.drawString ("pedro" + i, 10, 10);
////		}
////		g2d.translate (fm.getAscent (), fm.stringWidth (verticalAxisLabel) + 10);
//	}
////	protected void drawString (Graphics g, String s, int x, int y, double angle)
////	{
////		Graphics2D g2d = (Graphics2D) g;
////		g2d.a
////	}
//	protected void drawArrow (Graphics g, int x0, int y0, int x1, int y1)
//	{
//		double angle = Math.atan2 (y1 - y0, x1 - x0);
//		g.drawLine (x0, y0, x1, y1);
//		g.drawLine (x1, y1,
//			x1 + (int) (5 * Math.cos (angle + 3 * Math.PI / 4)),
//			y1 + (int) (5 * Math.sin (angle + 3 * Math.PI / 4)));
//		g.drawLine (x1, y1,
//			x1 + (int) (5 * Math.cos (angle - 3 * Math.PI / 4)),
//			y1 + (int) (5 * Math.sin (angle - 3 * Math.PI / 4)));
//	}
	static protected final int MIN_DISTANCE_I = 10;
	/**
	 * Minimum distance to show tool tip text.
	 */
	static protected final Rational MIN_DISTANCE_R = new Rational (MIN_DISTANCE_I);

	/**
	 * Listener responsible for dealing with events related to the component that shows state history.
	 */
	private class Listener
		  extends java.awt.event.ComponentAdapter
	{
		/**
		 * Whenever the user resizes the window, we adjust the number x range.
		 * @param e
		 */
		@Override
		public void componentResized (ComponentEvent e)
		{
			adjustXRange ();
		}
	}
//	class HistoryData
//		extends Plot2D.AbstractData
//	{
//		HistoryData
//		public int size ()
//		{
//			return history.size ();
//		}
//	}
}
